package v2.chapter3.mq.test2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;

public class MQSendAndReceiveUtil {

	private MQQueueManager qManager;
	private MQQueue queue;

	/* 发送端
	// 队列管理器
	private static String qmManager = "QM1";
	// 远程队列名称
	private static String remoteQName = "RQ_8888";
	// 本地队列
	private static String localQName = "LQ_0000";
	// 本机名称
	private static String hostName = "192.168.1.121";
	// 服务器链接通道
	private static String channel = "JMS_RECEIVE";
	// 编码字符集标识
	private static int ccsid = 1381;
	// TCP 端口
	private static int port = 1411;*/
	
	// 接收端
	// 队列管理器
	private static String qmManager = "IB9QMGR";
	// 远程队列名称
	private static String remoteQName = "RQ_0000";
	// 本地队列
	private static String localQName = "LQ_0000";
	// 本机名称
	private static String hostName = "192.168.1.77";
	// 服务器链接通道
	private static String channel = "JMS_RECEIVE";
	// 编码字符集标识
	private static int ccsid = 1381;
	// TCP 端口
	private static int port = 1411;

	private MQSendAndReceiveUtil() {
		MQEnvironment.hostname = hostName;
		MQEnvironment.channel = channel;
		MQEnvironment.CCSID = ccsid;
		MQEnvironment.port = port;
		MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);

		try {
			qManager = new MQQueueManager(qmManager);
		} catch (MQException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 如果队列管理器为空，则建立
	 */
	private void createConntection() {
		if (qManager == null) {
			new MQSendAndReceiveUtil();
		}
	}

	/**
	 * 释放资源
	 */
	public void closeAction() {
		try {
			if (queue != null) {
				queue.close();
				queue = null;
			}

			if (qManager != null) {
				qManager.disconnect();
				qManager.close();
				qManager = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 发送文件
	 * 
	 * @param fileName
	 */
	public void sendFileMessage(String fileName) {
		this.createConntection();

		try {
			// 建立打开方式
			int openOptions = MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING;
			// 连接队列（发送时此队列为发送远方的远程队列）
			queue = qManager.accessQueue(remoteQName, openOptions, null, null, null);
			// 创建消息放入方式实例
			MQPutMessageOptions pmo = new MQPutMessageOptions();
			// 创建MQ消息实例
			MQMessage message = new MQMessage();

			// 创建FileBean对象实例并赋值
			FileBean file = new FileBean();
			// 获取文件路径
			Path path = Paths.get(fileName);
			// 设置文件名称
			file.setFileName(path.getFileName().toString());
			// 输入流读取要发送的文件
			InputStream in = new FileInputStream(fileName);

			byte[] data = new byte[in.available()];
			in.read(data);

			// 创建BASE64Encoder编码实例
			BASE64Encoder encoder = new BASE64Encoder();
			String content = encoder.encode(data);

			file.setFileContent(content);
			// 将FileBean实例 file放入消息中发送
			message.writeObject(file);
			// 将消息放入队列
			queue.put(message, pmo);

			this.logInfo("文件发送成功！");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			this.closeAction();
		}
	}

	/**
	 * 获取文件信息
	 */
	public void receiveFileMessage(String filePath) {
		try {
			// 建立队列打开方式
			int openOptions = MQC.MQOO_INPUT_SHARED | MQC.MQOO_FAIL_IF_QUIESCING;
			// 连接队列（接收时队列名为接收方的本地队列）
			queue = qManager.accessQueue(localQName, openOptions, null, null, null);
			// MQ接收消息方式
			MQGetMessageOptions gmo = new MQGetMessageOptions();
			// 同步接收
			gmo.options = gmo.options + MQC.MQGMO_SYNCPOINT;
			// 没消息等待
			gmo.options = gmo.options + MQC.MQGMO_WAIT;
			// 停顿则失败
			gmo.options = gmo.options + MQC.MQGMO_FAIL_IF_QUIESCING;
			// 等待间隔
			gmo.waitInterval = 100;

			// 创建消息实例
			MQMessage inMsg = new MQMessage();
			// 从队列中获取消息
			queue.get(inMsg, gmo);

			FileBean fileBean = new FileBean();
			// 读取消息强转为FileBean类型
			fileBean = (FileBean) inMsg.readObject();
			// 获取文件内容
			String content = fileBean.getFileContent();
			// 建立解码类实例
			BASE64Decoder decoder = new BASE64Decoder();
			// 解码生成byte数组
			byte[] contentArray = decoder.decodeBuffer(content);

			File file = new File(filePath);
			// 生成文件路径
			if (!file.exists()) {
				file.mkdirs();
			}

			// 构建文件路径
			String path = filePath + fileBean.getFileName();

			// 调动输出流把文件写到指定的位置
			FileOutputStream out = new FileOutputStream(new File(path));
			// 输出文件
			out.write(contentArray, 0, contentArray.length);
			// 提交事务
			qManager.commit();
			// 打印日志
			this.logInfo("文件接收成功，请注意查收");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			this.closeAction();
		}
	}

	/**
	 * 打印日志信息
	 * 
	 * @param message
	 */
	public void logInfo(String message) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
		System.out.println("【" + format.format(new Date()) + "】" + message);
	}

	public static void main(String[] args) {
		//new MQSendAndReceiveUtil().sendFileMessage("HJBH_SSDZXX_41000020190617000096.xml");
		
		// new MQSendAndReceiveUtil().receiveFileMessage("F:\\222\\");
	}
}